﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFShapeDrawing
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
      Line SideA;
      Line SideB;
      Line SideC;
      TextBlock txt1;
      TextBlock txt2;
      TextBlock txt3;

    public MainWindow()
    {

      InitializeComponent();
      // Add a Line Element

    }

    public class Triangle
    {
        public double[] side = { 0, 0, 0 };
        public double[] angle = { 0, 0, 0 };

        public void setSides(double[] measurement)
        {
            side = measurement;
        }

        public void setAngles(double[] measurement)
        {
            angle = measurement;
        }
        public int getCase(int SumOfAngles, int SumOfSides)
        {
            if (SumOfAngles >= 2 && SumOfSides == 0)
                return 1;
            else if (SumOfAngles >= 2 && SumOfSides == 1)
                return 2;
            else if (SumOfAngles >= 1 && SumOfSides == 2)
                return 3;
            else if (SumOfSides == 3)
                return 4;
            else
                return 0;
        }

        public double[] Case1(int SumOfAngles, double[] AngleExist)
        {

            if (SumOfAngles == 3)
            {
                if ((angle.Sum()) > 180)
                {
                    MessageBox.Show("Error");
                    //return;
                }
            }
            else
            {
                for (int i = 0; i < 2; i++)
                {
                    if (AngleExist[i] == 0)
                        angle[i] == 180 - angle[(i + 1) % 3] - angle[(i + 2) % 3];
                }
            }

            //Find the maximum angle
            int k = 0;
            for (int i = 1; i < 3; i++)
            {
                if (angle[k] < angle[i])
                    k = i;
            }

            //Set the longest side 250 (250 is x here)
            side[k] = 250;

            //Find other sides
            for (int i = 0; i < 3; i++)
            {
                if (i == k)
                    continue;
                side[i] = side[k] * Math.Sin(ToRadians(angle[i])) / Math.Sin(ToRadians(angle[k]));
            }

            //Define the coordinates
            double[] triangleCoordinates = new double[6];
            triangleCoordinates[0] = 0;
            triangleCoordinates[1] = 0;
            triangleCoordinates[2] = 0 - side[2] * Math.Cos(ToRadians(angle[0]));
            triangleCoordinates[3] = side[2] * Math.Sin(ToRadians(angle[0]));
            triangleCoordinates[4] = side[0] * Math.Cos(ToRadians(angle[2]));
            triangleCoordinates[5] = triangleCoordinates[3];

            return triangleCoordinates;
        }
        public void solve()
        {
            int[] AngleExist = { 0, 0, 0 };
            int[] SideExist = { 0, 0, 0 };
            int SumOfAngles, SumOfSides;

            for(int i = 0; i < 2; i++){
                if (angle[i] != 0) AngleExist[i] = 1;
                if (side[i] != 0) SideExist[i] = 1;
            }

            SumOfAngles = Convert.ToInt16(angleExist.Sum());
            SumOfSides = Convert.ToInt16(sideExist.Sum());

            switch (this.getCase(SumOfAngles, SumOfSides))
            {
                case 1:
                    
                case 2:
                case 3:
                case 4:
                //default:
                    //throw new Triangle.ArgumentEx
            }
        }
    }

    private void m_btnCalculate_Click(object sender, RoutedEventArgs e)
    {
      double anglealpha, anglebeta, anglegamma, sidea, sideb, sidec;
      int AngleAlphaExist, AngleBetaExist, AngleGammaExist, SideAExist, SideBExist, SideCExist, SumOfAngles, SumOfSides;

      // Check if the sides and angles were defined or not
      anglealpha = 0;
      anglebeta = 0;
      anglegamma = 0;
      if (m_tbAngle_alpha.Text != "")
      {
          if (!double.TryParse(m_tbAngle_alpha.Text, out anglealpha))
              return;
          else
              AngleAlphaExist = 1;
      }
      else AngleAlphaExist = 0;

      if (m_tbAngle_beta.Text != "")
      {
          if (!double.TryParse(m_tbAngle_beta.Text, out anglebeta))
              return;
          else
              AngleBetaExist = 1;
      }
      else AngleBetaExist = 0;

      if (m_tbAngle_gamma.Text != "")
      {
          if (!double.TryParse(m_tbAngle_gamma.Text, out anglegamma))
              return;
          else
              AngleGammaExist = 1;
      }
      else AngleGammaExist = 0;

      if (m_tbSide_a.Text != "")
      {
          if (!double.TryParse(m_tbSide_a.Text, out sidea))
              return;
          else
              SideAExist = 1;
      }
      else SideAExist = 0;

      if (m_tbSide_b.Text != "")
      {
          if (!double.TryParse(m_tbSide_b.Text, out sideb))
              return;
          else
              SideBExist = 1;
      }
      else SideBExist = 0;

      if (m_tbSide_c.Text != "")
      {
          if (!double.TryParse(m_tbSide_c.Text, out sidec))
              return;
          else
              SideCExist = 1;
      }
      else SideCExist = 0;

      SumOfAngles = AngleAlphaExist + AngleBetaExist + AngleGammaExist;
      SumOfSides = SideAExist + SideBExist + SideCExist;

     // MessageBox.Show(anglealpha.ToString());
     // MessageBox.Show(anglebeta.ToString());
     // MessageBox.Show(anglegamma.ToString());

      // Case of 2 angles or more and 0 sides
      //if (SumOfAngles >= 2 && SumOfSides == 0)
     // {
          if (SumOfAngles == 3)
          {
              if ((anglealpha + anglebeta + anglegamma) > 180)
              {
                  MessageBox.Show("Error");
                  return;
              }
          }
          else
          {
              if (AngleAlphaExist == 0)
              {
                  anglealpha = 180 - anglebeta - anglegamma;
              }
              else if (AngleBetaExist == 0)
              {
                  anglebeta = 180 - anglealpha - anglegamma;
              }
              else
              {
                  anglegamma = 180 - anglebeta - anglealpha;
              }
          }

          if (anglealpha >= anglebeta && anglealpha >= anglegamma)
          {
              sidea = 1;
              sideb = sidea * Math.Sin(ToRadians(anglebeta)) / Math.Sin(ToRadians(anglealpha));
              sidec = sidea * Math.Sin(ToRadians(anglegamma)) / Math.Sin(ToRadians(anglealpha));
          }else if(anglebeta >= anglealpha && anglebeta >= anglegamma){
              sideb = 1;
              sidea = sideb * Math.Sin(ToRadians(anglealpha)) / Math.Sin(ToRadians(anglebeta));
              sidec = sideb * Math.Sin(ToRadians(anglegamma)) / Math.Sin(ToRadians(anglebeta));
          }
          else
          {
              sidec = 1;
              sidea = sidec * Math.Sin(ToRadians(anglealpha)) / Math.Sin(ToRadians(anglegamma));
              sideb = sidec * Math.Sin(ToRadians(anglebeta)) / Math.Sin(ToRadians(anglegamma));
          }
      //}      
      //double Unit = 300;
      //double OriginX = 250;
      //double OriginY = 300;

      m_gridDrawing.Children.Remove(SideA);
      m_gridDrawing.Children.Remove(SideB);
      m_gridDrawing.Children.Remove(SideC);
      m_gridDrawing.Children.Remove(txt1);
      m_gridDrawing.Children.Remove(txt2);
      m_gridDrawing.Children.Remove(txt3);

      SideC = new Line();
      SideC.StrokeThickness = 2;
      SideC.Stroke = System.Windows.Media.Brushes.Black;

      SideB = new Line();
      SideB.StrokeThickness = 2;
      SideB.Stroke = System.Windows.Media.Brushes.Black;

      SideA = new Line();
      SideA.StrokeThickness = 2;
      SideA.Stroke = System.Windows.Media.Brushes.Black;

      double x1, x2, x3, y1, y2, y3;
      double[] tc = new double[6];
      tc = generateTriangle(anglealpha, anglebeta, anglegamma);
      tc = centralizeCentroid(tc[0], tc[1], tc[2], tc[3], tc[4], tc[5]);
      x1 = tc[0];
      y1 = tc[1];
      x2 = tc[2];
      y2 = tc[3];
      x3 = tc[4];
      y3 = tc[5];
      

      /*VertLeg.X1 = OriginX;
      VertLeg.Y1 = OriginY;
      VertLeg.X2 = OriginX;
      VertLeg.Y2 = OriginY - Math.Sin(ToRadians(anglealpha)) * Unit;*/
      SideC.X1 = x1;
      SideC.Y1 = y1;
      SideC.X2 = x2;
      SideC.Y2 = y2;

      /*HorzLeg.X1 = OriginX;
      HorzLeg.Y1 = OriginY;
      HorzLeg.X2 = OriginX - Math.Cos(ToRadians(anglealpha)) * Unit;
      HorzLeg.Y2 = OriginY;*/
      SideB.X1 = x2;
      SideB.Y1 = y2;
      SideB.X2 = x3;
      SideB.Y2 = y3;

      /*Hypotenuse.X1 = HorzLeg.X2;
      Hypotenuse.Y1 = HorzLeg.Y1;
      Hypotenuse.X2 = VertLeg.X1;
      Hypotenuse.Y2 = VertLeg.Y2;*/

      SideA.X1 = x3;
      SideA.Y1 = y3;
      SideA.X2 = x1;
      SideA.Y2 = y1;

      double txt1x, txt1y, txt2x, txt2y, txt3x, txt3y;

      if (x1 > x2)
        {
            txt1x = (x1 - 20 + x2 - 20) / 2;
            txt1y = (y1 - 20 + y2 - 20) / 2;
            //MessageBox.Show("case1a");
        }
        else
        {
            txt1x = (x1 - 20 + x2 - 20) / 2;
            txt1y = (y1 + 10 + y2 + 10) / 2;
            //MessageBox.Show("case1b");
        }

      if (x3 > x1)
      {
          txt3x = (x3 + 12 + x1 + 12) / 2;
          txt3y = (y3 - 20 + y1 - 20) / 2;
          //MessageBox.Show("case1a");
      }
      else
      {
          txt3x = (x3 + 12 + x1 + 12) / 2;
          txt3y = (y3 + 10 + y1 + 10) / 2;
          //MessageBox.Show("case1b");
      } 


      txt1 = new TextBlock();
      //txt1.Text = "x";
      //MessageBox.Show(sidea.ToString());
      //MessageBox.Show(sideb.ToString());
      //MessageBox.Show(sidec.ToString());
      //MessageBox.Show(SumOfAngles.ToString());
      //MessageBox.Show(SumOfSides.ToString());
      if (SumOfAngles >= 2 && SumOfSides == 0)
      {
          if (sidec == 1) txt1.Text = "x";
          else txt1.Text = sidec.ToString() + "x";
      }
      else txt1.Text = sidec.ToString();
      txt1.FontSize = 14;
      txt1.FontWeight = FontWeights.Bold;
      txt1.FontFamily = new FontFamily("Century Gothic");
      txt1.RenderTransform = new TranslateTransform
      {
          X = txt1x,
          Y = txt1y
      };

      txt2 = new TextBlock();
      //txt2.Text = "y";
      if (SumOfAngles >= 2 && SumOfSides == 0)
      {
          if (sideb == 1) txt2.Text = "x";
          else txt2.Text = sideb.ToString() + "x";
      }
      else txt2.Text = sideb.ToString();
      txt2.FontSize = 14;
      txt2.FontWeight = FontWeights.Bold;
      txt2.FontFamily = new FontFamily("Century Gothic");
      txt2.RenderTransform = new TranslateTransform
      {
          X = (x2 + x3) / 2,
          Y = (y2 + 11.8 + y3 + 11.8) / 2
      };

      txt3 = new TextBlock();
      //txt3.Text = "z";
      if (SumOfAngles >= 2 && SumOfSides == 0)
      {
          if (sidea == 1) txt3.Text = "x";
          else txt3.Text = sidea.ToString() + "x";
      }
      else txt3.Text = sidea.ToString();
      txt3.FontSize = 14;
      txt3.FontWeight = FontWeights.Bold;
      txt3.FontFamily = new FontFamily("Century Gothic");
      txt3.RenderTransform = new TranslateTransform
      {
          X = txt3x,
          Y = txt3y
      };


      //MessageBox.Show(t1.ToString());
      //MessageBox.Show(t2.ToString());

      //txt1.VisualXSnappingGuidelines = 100;

      m_gridDrawing.Children.Add(SideA);
      m_gridDrawing.Children.Add(SideB);
      m_gridDrawing.Children.Add(SideC);
      m_gridDrawing.Children.Add(txt1);
      m_gridDrawing.Children.Add(txt2);
      m_gridDrawing.Children.Add(txt3);

    }

    double ToRadians(double Angle)
    {
      return Angle*Math.PI/180;
    }


    // This function will generate the coordenates of the triangle just using the 3 angles
    double[] generateTriangle(double anglealpha, double anglebeta, double anglegamma)
    {
        // Vector containing all the 6 coordinates of each vertex of the triangle
        double[] triangleCoordinates = new double[6];
        // Variables of the measurement of each side of the triangle
        double a, b, c;

        // These conditions will decide which side is the largest in order to set 250 in this same side
        // So, the triangle will never get out the frame
        
        // If the angle alpha is the largest, so side a is the largest side
        if (anglealpha >= anglebeta && anglealpha >= anglegamma)
        {
            a = 250;
            c = a * Math.Sin(ToRadians(anglegamma)) / Math.Sin(ToRadians(anglealpha));
        }
        // If the angle beta is the largest, so side b is the largest side
        else if (anglebeta >= anglealpha && anglebeta >= anglegamma)
        {
            b = 250;
            a = b * Math.Sin(ToRadians(anglealpha)) / Math.Sin(ToRadians(anglebeta));
            c = b * Math.Sin(ToRadians(anglegamma)) / Math.Sin(ToRadians(anglebeta));
        }
        // If the angle gamma is the largest, so side c is the largest side
        else
        {
            c = 250;
            a = c * Math.Sin(ToRadians(anglealpha)) / Math.Sin(ToRadians(anglegamma));
        }

        // Define the coordinates
        triangleCoordinates[0] = 0;
        triangleCoordinates[1] = 0;
        triangleCoordinates[2] = 0 - c * Math.Cos(ToRadians(anglealpha));
        triangleCoordinates[3] = 0 + c * Math.Sin(ToRadians(anglealpha));
        triangleCoordinates[4] = triangleCoordinates[1] + a * Math.Cos(ToRadians(anglegamma));
        triangleCoordinates[5] = triangleCoordinates[3];

        return triangleCoordinates;
    }

    // This function will centralize the triangle in the frame calculating its centroid and putting the triangle's centroid
    // in the center of the frame
    double[] centralizeCentroid(double x1, double y1, double x2, double y2, double x3, double y3)
    {
        // Vector containing all the 6 coordinates of each vertex of the triangle
        double[] triangleCoordinates = new double[6];
        // Variables used to calculate the difference comparing to the centroid
        double CentroidXfac;
        double CentroidYfac;

        // The center of the frame is seted as (200, 150)
        CentroidXfac = 200 - ((x1 + x2 + x3) / 3);
        CentroidYfac = 150 - ((y1 + y2 + y3) / 3);

        // Centralize the triangle in the frame
        triangleCoordinates[0] = x1 + CentroidXfac;
        triangleCoordinates[1] = y1 + CentroidYfac;
        triangleCoordinates[2] = x2 + CentroidXfac;
        triangleCoordinates[3] = y2 + CentroidYfac;
        triangleCoordinates[4] = x3 + CentroidXfac;
        triangleCoordinates[5] = y3 + CentroidYfac;

        return triangleCoordinates;
    }

    //This is the case when we have 2 or 3 angles
    //Assume that angles which are not input have value 0
    //When a user input the second angles, check the sum of angles is smaller than 180,
    //and if so, calcualate the other angle.
    //Therefore, we do not need to check the angles here
    double[] Case1(double[] angles)
    {

        //Find the maximum angle
        int k = 0;
        for (int i = 1; i < 3; i++)
        {
            if (angles[k] < angles[i])
                k = i;
        }

        double[] sides = new double[3];
        //Set the longest side 250 (250 is x here)
        sides[k] = 250;

        //Find other sides
        for (int i = 0; i < 3; i++)
        {
            if (i == k)
                continue;
            sides[i] = sides[k] * Math.Sin(ToRadians(angles[i])) / Math.Sin(ToRadians(angles[k]));
        }

        //Define the coordinates
        double[] triangleCoordinates = new double[6];
        triangleCoordinates[0] = 0;
        triangleCoordinates[1] = 0;
        triangleCoordinates[2] = 0 - sides[2] * Math.Cos(ToRadians(angles[0]));
        triangleCoordinates[3] = sides[2] * Math.Sin(ToRadians(angles[0]));
        triangleCoordinates[4] = sides[0] * Math.Cos(ToRadians(angles[2]));
        triangleCoordinates[5] = triangleCoordinates[3];

        return triangleCoordinates;
    }

    //If error happens, return null
    double[] Case4(double[] sides)
    {
        //Error Check
﻿      int k = 0;
﻿      double sum = sides[0];
﻿      for(int i = 0; i<sides.Length; i++){
﻿  ﻿      if(sides[k] < sides[i])
﻿  ﻿  ﻿      k = i;
﻿  ﻿      sum += sides[i];
﻿      }
﻿      if(sum - sides[k] <= sides[k]){
﻿  ﻿      //Display Error Message
﻿  ﻿      return null;
﻿      }

        double[] angles = new double[3];
        angles[0] = Math.Acos((Math.Pow(sides[1], 2.0) + Math.Pow(sides[2], 2.0) - Math.Pow(sides[0], 2.0)/(2*sides[1]*sides[2])));
        angles[2] = Math.Acos((Math.Pow(sides[0], 2.0) + Math.Pow(sides[1], 2.0) - Math.Pow(sides[2], 2.0)/(2*sides[0]*sides[1])));

        //Define the coordinate
        double[] triangleCoordinates = new double[6];
        triangleCoordinates[0] = 0;
        triangleCoordinates[1] = 0;
        triangleCoordinates[2] = 0 - sides[2] * Math.Cos(angles[0]);
        triangleCoordinates[3] = sides[2] * Math.Sin(angles[0]);
        triangleCoordinates[4] = sides[0] * Math.Cos(angles[2]);
        triangleCoordinates[5] = triangleCoordinates[3];

        return triangleCoordinates;
    }

  }
}
